package dataProcess;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashMap;

import jxl.Workbook;
import jxl.Sheet;

import org.ejml.data.DenseMatrix64F;
import org.ejml.ops.CommonOps;
import org.ejml.ops.MatrixIO;

import termWeighting.PrepareTF;
import type.TfType;
import ds.BugInfo;
import ds.Constants;
import dataProcess.StringSpliter;

public class ReadExcel {

	private ArrayList<String> labels;
	private int BugId;
	
	/**
	 * TODO args[i] -> new String(args[i])
	 * @param args
	 */
	public ReadExcel(String[] args){
		this.BugId = 1;
		this.labels = new ArrayList<String>();
		for(int i = 0; i < args.length; i++){
			this.labels.add(args[i]);
		}
	}
	
	public ArrayList<String> getLabels(){
		return this.labels;
	}
	
	public static void main(String args[]){
	
		System.out.print("completed!");
		//ArrayList<BugInfo> allBugs = 	getBalanceMsBugs("data/input/BugReports-20121231-200618.xls");
		//ArrayList<BugInfo> allBugs = 	getAllBugs("data/input/BugReports-20121231-200618.xls");
		//HashMap<String, String> bugId2Class = getGroundTruth(allBugs);
		//bug2TextFile(allBugs, "output/allBugs.txt");
		//matrixBuilder("data/input/wvToolTfIdf.txt", bugId2Class);
		//translateToArff("data/input/wvToolTfIdf.txt", "data/input/wvToolWordlist.txt", "output/Micro.arff", bugId2Class);
	}
	
	/**
	 * 
	 * @param fileName is name of excel file
	 * @param IDindex is column index of bug id (0)
	 * @param textIndexes is column indexes of text content(10)
	 * @param labelIndex is column index of category(6)
	 * @return
	 */
	public ArrayList<BugInfo> getBugsFromXls(String fileName, int[] textIndexes, int labelIndex){
		ArrayList<BugInfo> allBugs = new ArrayList<BugInfo>();
		int rowCount;
		try{
			Workbook wb = Workbook.getWorkbook(new File(fileName));
			Sheet sheet = wb.getSheet(0);
			rowCount = sheet.getRows();
			StringSpliter ss = StringSpliter.getDefaultSpliter();
			
			/**
			 * i = 1 because all excel files have titles
			 */
			for(int i = 1; i < rowCount; i++){
				String label = sheet.getCell(labelIndex, i).getContents();
				if(!this.labels.contains(label))
					continue;
				BugInfo bug = new BugInfo();
				bug.label = label;
				bug.bugID = "" + this.BugId;
				this.BugId++;
				StringBuilder cotentBuilder = new StringBuilder();
				for(int textIndex : textIndexes){
					cotentBuilder.append(sheet.getCell(textIndex, i).getContents());
				}
				bug.content = cotentBuilder.toString();
				bug.content = ss.simpleSplitSentenceIntoWords(bug.content);
				
				if(!bug.content.equals(""))
					allBugs.add(bug);
			}
			
		}catch(Exception e){
			System.out.println(e.getStackTrace());
		}
		return allBugs;
	}
	
	/**
	 * 
	 * @throws Exception
	 */
	public ArrayList<BugInfo> getDaiBugs() {
		try {
			ArrayList<BugInfo> DaiBugs = new ArrayList<BugInfo>();
			int row = 0;
			Workbook wb = Workbook.getWorkbook(new File(
					"data/input/DaiLabel.xls"));
			Sheet sheet = wb.getSheet(0);
			StringSpliter ss = StringSpliter.getDefaultSpliter();

			File dir = new File("data/input/DaiText/");
			if (!dir.exists())
				System.out.println("[ERROR] File Path Not Exist");
			else {
				File[] files = dir.listFiles();
				for (File file : files) {
					BugInfo bug = new BugInfo();

					String label = sheet.getCell(1, row).getContents();
					if (!this.labels.contains(label)) {
						row++;
						continue;
					}
					StringBuilder sBuilder = new StringBuilder();
					BufferedReader br = new BufferedReader(new FileReader(file));
					while (true) {
						String str = br.readLine();
						if (str == null)
							break;
						else
							sBuilder.append(str);
					}
					br.close();

					bug.bugID = "" + this.BugId;
					bug.label = label;
					bug.content = sBuilder.toString();
					bug.content = ss.simpleSplitSentenceIntoWords(bug.content);
					DaiBugs.add(bug);

					this.BugId++;
					row++;
				}
			}
			return DaiBugs;
		} catch (Exception e) {
			return null;
		}
	}
	
	/**
	 * index: 0 is positive, 1 is negative
	 * @param fileName
	 * @return
	 */
	public static ArrayList<ArrayList<BugInfo>> getPosAndNon(ArrayList<BugInfo> allBugs, String className){
		ArrayList<ArrayList<BugInfo>> bugSet = new ArrayList<ArrayList<BugInfo>>();
		ArrayList<BugInfo> posBugs = new ArrayList<BugInfo>();
		ArrayList<BugInfo> nonBugs = new ArrayList<BugInfo>();
		
		for(BugInfo curBug : allBugs){
			String curLabel = curBug.label;
			if(curLabel.equals(className))
				posBugs.add(curBug);
			else
				nonBugs.add(curBug);
		}
		
		bugSet.add(posBugs);
		bugSet.add(nonBugs);
		return bugSet;
	}
	
	public ArrayList<BugInfo> getSecurityBugs(String fileName){
		ArrayList<BugInfo> secBugs = new ArrayList<BugInfo>();
		StringSpliter ss = StringSpliter.getDefaultSpliter();
		try {
			BufferedReader br = new BufferedReader(new FileReader(fileName));
			for(String content = br.readLine(); content != null; content = br.readLine()){
				BugInfo bug = new BugInfo();
				bug.bugID = "" + this.BugId;
				bug.label = "Security";
				bug.content = ss.simpleSplitSentenceIntoWords(content);
				
				secBugs.add(bug);
				this.BugId++;
			}
			br.close();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return secBugs;
	}
	
	/**
	 * get word-label matrix 
	 * @param fileName
	 * @param bugId2Class
	 * @return
	 */
	private 	DenseMatrix64F matrixBuilder(String fileName, HashMap<String, String> bugId2Class){
		try {
			
			BufferedReader br =  new BufferedReader(new FileReader(fileName));
			String summery = br.readLine();
			String[] units = summery.split(" ");
			int wordCount = Integer.parseInt(units[0].split(":")[1]);
			int trainBugCount = Integer.parseInt(units[1].split(":")[1]);
			int testBugCount = Integer.parseInt(units[2].split(":")[1]);
			DenseMatrix64F result = new DenseMatrix64F(wordCount, 4);
			//construct matrix		
			for(int i = 0; i < trainBugCount; i++ ){
				String wordVector = br.readLine();
				String[] words = wordVector.split(" ");
				String bugId = words[0].substring(0, words[0].length()-1);
				String label = bugId2Class.get(bugId);
				int classIndex = this.labels.indexOf(label);
				for(int j=1; j<words.length; j++){
					int wordIndex = Integer.parseInt(words[j].split(":")[0]);
					result.set(wordIndex, classIndex, result.get(wordIndex, classIndex)+1);
				}
			}
			PrintStream ps0 = new PrintStream("output/matrix_0.txt");
			MatrixIO.print(ps0, result, 10, 8);
			DenseMatrix64F rowSum = new DenseMatrix64F(result.numRows, 1);
			CommonOps.sumRows(result, rowSum);
			for(int row=0; row<result.numRows;row++)
				for(int col = 0; col<result.numCols; col++){
					if(rowSum.get(row, 0) !=0)
						result.set(row, col, result.get(row, col)/rowSum.get(row, 0));
				}
			PrintStream ps = new PrintStream("output/matrix.txt");
			MatrixIO.print(ps, result, 10, 8);
			//test
			int correctNum=0;
			int[] record = new int [result.numCols];
			for(int x=0; x<record.length; x++){
				record[x] = 0;		
			}
			for(int i=0; i<testBugCount; i++){
				String tsetVector = br.readLine();
				String[] testWords = tsetVector.split(" ");
				String bugId = testWords[0].substring(0, testWords[0].length()-1);
				int realCateIndex = this.labels.indexOf(bugId2Class.get(bugId));
				
				
				double[] p = new double[result.numCols];
				for(int x=0; x<p.length; x++){
					p[x] = 0;			
				}
				for(int col = 0; col<result.numCols; col++){
					for(int j=1; j<testWords.length; j++){
						int wordIndex = Integer.parseInt(testWords[j].split(":")[0]);
						p[col] = p[col] + result.get(wordIndex, col);
					}
				}
				
				int myCateIndex = 0;
				double pMAX = 0;
				for(int x=0; x<p.length; x++){
					if(p[x] >= pMAX){
						pMAX = p[x];
						myCateIndex = x;
					}				
				}
				if(realCateIndex == myCateIndex){
					correctNum++;
					record[realCateIndex]++;
				}
			}
			br.close();
			System.out.println("total:"+(double)correctNum*100/testBugCount + "%");
			System.out.println("0:"+(double)record[0]*100/8 + "%");
			System.out.println("1:"+(double)record[1]*100/4 + "%");
			System.out.println("2:"+(double)record[2]*100/8 + "%");
			System.out.println("3:"+(double)record[3]*100/8 + "%");
			return result;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
		
	}
	

}




